﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Dynamic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using Newtonsoft.Json;

namespace NFinal.Common.Plugin
{
    /// <summary>
    /// 依赖文件运行时实体类
    /// </summary>
    public class Runtimes
    {
        [JsonProperty("runtimes")]
        public SortedList<string, RuntimeIdentifier> RuntimeList;
    }
    /// <summary>
    /// 依赖文件解析实体类
    /// </summary>
    public class RuntimeIdentifier
    {
        [JsonProperty("#import")]
        public string[] Import { get; set; }
        private static Runtimes runtimes;
        static RuntimeIdentifier()
        {
            string runtimeJson = System.Text.Encoding.UTF8.GetString(Resource.runtime);
            runtimes = Newtonsoft.Json.JsonConvert.DeserializeObject<Runtimes>(runtimeJson);
        }
        public static bool IsFitNetCore30(string framework)
        {
            string[] frameDesc = framework.Split(',');
            string frameMain = frameDesc[0].Substring(1).ToLower();
            string frameVer = frameDesc[1].Substring(9);
            if (frameMain == "netcoreapp")
            {
                if (Version.TryParse(frameVer, out Version version))
                {
                    if (version.Major <= 3)
                    {
                        return true;
                    }
                }
            }
            return false;
        }
        /// <summary>
        /// 获取框架信息
        /// </summary>
        /// <param name="framework"></param>
        /// <returns></returns>
        public static string GetFrameworkIdentity(string framework)
        {
            string[] frameDesc = framework.Split(',');
            string frameMain = frameDesc[0].Substring(1).ToLower();
            string frameVer = frameDesc[1].Substring(9);
            return frameMain + frameVer;
        }
        /// <summary>
        /// 获取当前的运行环境
        /// </summary>
        /// <returns></returns>
        public static (string,string) GetCurrentRuntime()
        {
            string rootRuntime = null;
            string subRootRuntime = null;
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                rootRuntime = "win";
                subRootRuntime = "win-"+ RuntimeInformation.OSArchitecture;
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                rootRuntime = "linux";
                subRootRuntime = "linux-"+ RuntimeInformation.OSArchitecture;
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                rootRuntime = "osx";
                subRootRuntime = "osx-"+ RuntimeInformation.OSArchitecture;
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD))
            {
                rootRuntime = "freebsd";
                subRootRuntime = "freebsd-"+ RuntimeInformation.OSArchitecture;
            }
            else
            {
                rootRuntime = "base";
                subRootRuntime = "any";
            }
            return (rootRuntime,subRootRuntime.ToLower());
        }
        /// <summary>
        /// 检测该环境包是否属于某个环境
        /// 例如win7-x64包属于win-x64环境
        /// </summary>
        /// <param name="runtimeFolderName">运行环境包名称</param>
        /// <param name="runtime">运行环境</param>
        /// <returns></returns>
        public static bool IsBelongToRuntime(string runtimeFolderName,string runtime)
        {
            if (runtime == null)
            {
                throw new ArgumentNullException("runtime不能为空");
            }
            if (runtime == runtimeFolderName)
            {
                return true;
            }
            else
            {
                if (runtimes.RuntimeList.TryGetValue(runtimeFolderName, out RuntimeIdentifier runtimeIdentifier))
                {
                    var b = FindRuntimeNode(runtimeIdentifier, runtime);
                    return b;
                }
                else
                {
                    throw new ArgumentException("参数错误!");
                }
            }
        }
        /// <summary>
        /// 查找符合当前运行环境的节点
        /// </summary>
        /// <param name="runtimeIdentifier"></param>
        /// <param name="rootNode"></param>
        /// <returns></returns>
        private static bool FindRuntimeNode(RuntimeIdentifier runtimeIdentifier,string rootNode)
        {
            for (int i = 0; i < runtimeIdentifier.Import.Length; i++)
            {
                if (runtimeIdentifier.Import[i] == "base")
                {
                    return false;
                }
                if (rootNode== runtimeIdentifier.Import[i])
                {
                    return true;
                }
                else
                {
                    var nextRuntimeIdentifier = runtimes.RuntimeList[runtimeIdentifier.Import[i]];
                    var getNode= FindRuntimeNode(nextRuntimeIdentifier, rootNode);
                    if (getNode)
                    {
                        return true;
                    }
                }
            }
            return false;
        }
    }
}
